#pragma once

#include <AVUIDecorator.h>
#include <AVUICornerRadius.h>
#include <AVUIPanel.h>

namespace AVUI {

class StreamGeometry;
class StreamGeometryContext;

class Border : public Decorator
{
public:

    DECLARE_ELEMENT(Border, Decorator);

    virtual ~Border() { }

    DECLARE_DEPENDENCY_PROPERTY(BorderThickness);
    Thickness get_BorderThickness() { return AVUI::UnboxValue<Thickness>(GetValue(get_BorderThicknessProperty())); }
    void set_BorderThickness(const Thickness& value) { SetValue(get_BorderThicknessProperty(), AVUI::BoxValue(value)); } 

    DECLARE_DEPENDENCY_PROPERTY(Padding);
    Thickness get_Padding() { return AVUI::UnboxValue<Thickness>(GetValue(get_PaddingProperty())); }
    void set_Padding(const Thickness& value) { SetValue(get_PaddingProperty(), AVUI::BoxValue(value)); } 

    DECLARE_DEPENDENCY_PROPERTY(CornerRadius);
    CornerRadius get_CornerRadius() { return AVUI::UnboxValue<CornerRadius>(GetValue(get_CornerRadiusProperty())); }
    void set_CornerRadius(const CornerRadius& value) { SetValue(get_CornerRadiusProperty(), AVUI::BoxValue(value)); } 

    DECLARE_DEPENDENCY_PROPERTY(BorderBrush);
    TRefCountedPtr<Brush> get_BorderBrush() { return (Brush*)(Object*)GetValue(get_BorderBrushProperty()); }
    void set_BorderBrush(Brush* pValue) { SetValue(get_BorderBrushProperty(), (Object*)pValue); } 

    DECLARE_DEPENDENCY_PROPERTY(Background);
    TRefCountedPtr<Brush> get_Background() { return (Brush*)(Object*)GetValue(get_BackgroundProperty()); }
    void set_Background(Brush* pValue) { SetValue(get_BackgroundProperty(), (Object*)pValue); } 

protected:


    virtual Size MeasureOverride(const Size& constraintSize);
    virtual Size ArrangeOverride(const Size& constraintSize);
    virtual void OnRender(DrawingContext& drawingContext);

private:
    static void StaticConstructor();    
    static bool IsThicknessValid(Object* pValue);
    static bool IsCornerRadiusValid(Object* pValue);

    Size HelperCollapseThickness(const Thickness& th);
    Rect HelperDeflateRect(const Rect& rt, const Thickness& thick);
    bool AreUniformCorners(const CornerRadius& borderRadii);

    struct Radii
    {
        float LeftTop;
        float TopLeft;
        float TopRight;
        float RightTop;
        float RightBottom;
        float BottomRight;
        float BottomLeft;
        float LeftBottom;
        Radii(const CornerRadius& radii, const Thickness& borders, bool outer);
    };

    void GenerateGeometry(StreamGeometryContext* pCtx, const Rect& rect, const Radii& radii);

    bool m_useComplexRenderCodePath;
    TRefCountedPtr<StreamGeometry> m_pBorderGeometry;
    TRefCountedPtr<StreamGeometry> m_pBackgroundGeometry;

};


}; // namespace AVUI
